home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
fdu
/
fdu.c
next >
Wrap
C/C++ Source or Header
|
1993-11-30
|
61KB
|
1,652 lines
/*-------------------------------------------------------------------*/
/* */
/* FDU (Floppy Disk Utility) Ver. 0.91 */
/* */
/* for FM TOWNS or FMR */
/* */
/* Debug Date 930401-930818 */
/* */
/* Free Ware Collection 7 Release Date '93-08-18 By T.O6809 */
/* */
/*-------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <dos.h>
#include <limits.h>
#include <process.h>
#include <io.h>
#include <fcntl.h>
#define VER "0.91"
#define DEBUG 0
#define CSL_OFF() printf("\x1B[1v")
#define CSL_ON() printf("\x1B[0v")
#define CSL_TOP() printf("\x1B[80D")
#define DEL_STR() printf("\x1B[1K")
#define COLOR_RED() printf("\x1B[31m")
#define COLOR_WHITE() printf("\x1B[37m")
#define BEEP() printf("\x7")
#define MFM 0x00 /* 記録方式 */
#define FM 0x80
#define HD2 0x00 /* FD Type */
#define Hd2 0x50
#define DD2 0x10
#define D2 0x20
#define L0128 0x00 /* Sector Length */
#define L0256 0x01
#define L0512 0x02
#define L1024 0x03
#define F640 1
#define F720 2
#define F1200 3
#define F1232 4
#define F1440 5
#define FRM 10
#define FRM_FAT 20
#define DCP 30
#define DCP_EMS 31
#define ON 1
#define OFF 0
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned char uchar;
int drv_cnt = 0; /* Drive Count */
int drv_media; /* 0:FD 1:? 2:HD 3:RAM Disk ff:? */
int odno[128]; /* Drive Number */
uint odtp = 0xffff; /* 1:640k 2:720k 3:1200k 4:1232k */
uint orpt = 1; /* Repeat Count */
uint ohlp = 0; /* Help Messge */
uint odbg = 0; /* */
uint obep = 0; /* */
uint otyp = 0; /* 1:Format 2:Format(FAT) 3:DiskCopy */
uint dtp2; /* 1:640k 2:720k 3:1200k 4:1232k */
uint cc_cnt = 0; /* */
uint rpt_cnt; /* */
int ems_handle;
int ems_flg = 0;
typedef struct {
uchar trackno; /* トラック番号 */
uchar headno; /* ヘッド番号 */
uchar secno; /* セクタ番号 */
uchar seclen; /* セクタ長 */
uchar crc1;
uchar crc2;
} DKB_SEC;
uchar buf1[13000];
static int pr[][15] = { /* FD Format Information */
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14*/
/* SecLenDLenSecTrkHedGap3Gap4Gap0Sync Gap1Gap2 Byte/Sector*/
D2,MFM,L0256, 256,16,40, 2, 54,152,80, 12, 96,50, 22, 0,/* 320K 2D FM-7*/
DD2,MFM,L0512, 512, 8,80, 2, 84,310,80, 12, 96,50, 22, 656,/* 640K 2DD */
DD2,MFM,L0512, 512, 9,80, 2, 84,182,80, 12, 96,50, 22, 656,/* 720K 2DD */
HD2,MFM,L0512, 512,15,80, 2, 84,400,80, 12, 96,50, 22, 656,/*1200K 2HC */
HD2,MFM,L1024,1024, 8,77, 2,116,654,80, 12, 96,50, 22,1200,/*1232K 2HD */
Hd2,MFM,L0512, 512,18,80, 2,108,400,80, 12, 96,50, 22, 680,/*1440K 2HD */
HD2,MFM,L0256, 256,26,77, 2, 54,598,80, 12, 96,50, 22, 370,/*1-77 8'2D IBM*/
HD2, FM,L0128, 128,26,77, 2, 27,247,40, 6, 54,20, 11, 186,/*0 8'2D IBM*/
};
uchar ipl[][19] = { /* FD IPL DATA */
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */
0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
0,0x02,0x02,0x01,0,0x02,0x70,0,0x00,0x05,0xFB,0x02,0,0x08,0,0x02,0, 0, 0,
0,0x02,0x02,0x01,0,0x02,0x70,0,0xA0,0x05,0xF9,0x03,0,0x09,0,0x02,0, 0, 0,
0,0x02,0x01,0x01,0,0x02,0xE0,0,0x60,0x09,0xF9,0x07,0,0x0F,0,0x02,0, 0, 0,
0,0x04,0x01,0x01,0,0x02,0xC0,0,0xD0,0x04,0xFE,0x02,0,0x08,0,0x02,0, 0, 0,
0,0x02,0x01,0x01,0,0x02,0xE0,0,0x40,0x0b,0xF0,0x09,0,0x12,0,0x02,0, 0, 0,
0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
};
char type[][32] = {
"F-BASIC [2D]",
"MS-DOS(640k 80* 8) [2DD]",
"MS-DOS(720k 80* 9) [2DD]",
"MS-DOS(1200k 80*15) [2HC]",
"MS-DOS(1232k 77* 8) [2HD]",
"MS-DOS(1440k 80*18) [2HD]",
"IBM(1-77) 77*26 [8'2D]",
"IBM(0) 77*26 [8'2D]"
};
int devno[4] = {0x20, 0x21, 0x22, 0x23};/* デバイス番号 */
int chk_opt(int, char *[]); /* Check Option */
void err_msg(int, ...); /* Error Messge */
void data_make(void); /* Format Data Make */
void fd_form(void); /* FD Format */
void fd_form_sub(int); /* FD Format Subroutine */
void init_ipl(int); /* FD Initialize IPL Data */
void fd_form_fat(void); /* FD Sector 0 Initialize */
void init_fat(int); /* FD Initialize FAT Data */
void fd_copy(void); /* FD Copy */
void fd_copy_sub(int, int); /* FD Copy Subroutine */
/* FD_Copy (EMS) */
void fd_copy_ems(int, int, int, int [], ulong, uchar huge *, int);
/* FD_Copy (Standard Memory) */
void fd_copy_mem(int, int, int, int [], ulong, uchar huge *);
int ems_alloc(ulong *, int *); /* EMS Memory Alloc */
int ems_chk(void); /* EMS Status Check */
int ems_map(int far *, int); /* EMS Map Set */
int ems_free(int); /* EMS Memory Free */
void fd_ready1(int); /* FD Ready */
void fd_ready2(int); /* FD Ready */
void fd_ready3(int); /* FD Ready */
void fd_mode_set(int); /* FD Mode Stet */
int fd_chk(int); /* FD Check */
void dump(uchar [], int); /* Dump */
void time_get(int *, int *, int *); /* Timer Get */
void interrupt far ctrl_c(void); /* CTRL+C Interrupt */
void end_fdu(void);
/* Call BIOS Function */
int uDKB_setmode(int, uint, uint); /* INT 93 00 */
int uDKB_rdmode(int, uint *, uint *); /* INT 93 01 */
int uDKB_rdstatus(int, uint *); /* INT 93 02 */
int uDKB_restore(int); /* INT 93 03 */
int uDKB_read(int, int, int, int, int, char *, int *); /* INT 93 05 */
int uDKB_read1(int, int, int, int, int, char huge *, int *);/* INT 93 05 */
int uDKB_write(int, int, int, int, int, char *, int *); /* INT 93 06 */
int uDKB_write1(int, int, int, int, int, char huge *, int *);/* INT 93 06 */
int uDKB_chksec(int , int , int , int , int , int *); /* INT 93 07 */
int uDKB_rdsecid(int, int, int, DKB_SEC *); /* INT 93 09 */
int uDKB_format(int, int, int, uchar *); /* INT 93 0A */
int system_get(uchar *); /* INT 8E 00 */
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int ret;
ret = chk_opt(argc, argv);
if (ret == 1) {
err_msg(1);
exit(1);
} else if (ret == 2) {
err_msg(2);
exit(1);
}
_dos_setvect(0x23, (void (interrupt far *)())ctrl_c);
CSL_OFF();
switch(otyp) {
case FRM: /* format */
data_make();
for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
fd_form();
}
break;
case FRM_FAT: /* format (FAT) */
for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
fd_form_fat();
}
break;
case DCP: /* Disk Copy */
case DCP_EMS:
for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
fd_copy();
}
if (otyp == DCP_EMS) {
ems_free(ems_handle);
ems_flg = 0;
}
break;
default:
break;
}
/*outp(0x20C, 0x11);
outp(0x20C, 0x12);*/
outp(0x208, 0x03); /* Motor OFF (bit4 0) */
CSL_ON();
return (0);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int chk_opt(int ac, char *av[])
{
int i, tmp, f_cnt = 0, ret = 0;
long wkl;
uchar machine_sts[200];
if (ac <= 1) {
ret = 1;
} else if (av[1][0] == '-' && av[1][1] == '?') {
ret = 1;
ohlp = ON;
} else {
system_get(&machine_sts[0]);
for (i = 1; i < ac; i++) {
if ((av[i][0] >= 'A' && av[i][0] <= 'p' && av[i][1] == ':') ||
(av[i][0] >= 'a' && av[i][0] <= 'p' && av[i][1] == ':') ) {
tmp = 0x30 + (toupper(av[i][0]) - 'A') * 2;
if ((drv_media = machine_sts[tmp+0]) == 0) {
odno[drv_cnt++] = machine_sts[tmp+1];
} else {
drv_cnt++;
ret = 2;
}
} else if (av[i][0] == '-') {
if (av[i][1] == 'c' && av[i][2] == (char)NULL) {
f_cnt++;
otyp = DCP;
} else if (av[i][1] == 'c' && av[i][2] == 'c' &&
av[i][3] == (char)NULL ) {
f_cnt++;
otyp = DCP_EMS;
} else if (av[i][1] == 'B') {
obep = ON;
} else if (av[i][1] == 'f') {
f_cnt++;
otyp = FRM;
if (av[i][2] == (char)NULL) {
odtp = F1232;
} else if (av[i][3] == (char)NULL) {
odtp = av[i][2] - '0';
if (!(odtp >= F640 && odtp <= F1440)) {
ret = 1;
}
} else {
ret = 1;
}
} else if (av[i][1] == 'F' && av[i][2] == (char)NULL) {
f_cnt++;
otyp = FRM_FAT;
} else {
ret = 1;
}
} else if (av[i][0] == '+') {/* Set Repeat Count */
if (isdigit(av[i][1])) {
wkl = atol(&av[i][1]);
if (wkl == 0 || wkl > UINT_MAX) {
ret = 1;
} else {
orpt = (uint)wkl;
}
} else {
if (av[i][1] == '+' && av[i][2] == (char)NULL) {
orpt = UINT_MAX;
} else {
ret = 1;
}
}
} else {
ret = 1;
}
}
}
if (otyp == DCP || otyp == DCP_EMS) {
if (drv_cnt == 2) { /* Disk Copy */
drv_cnt = 1;
} else {
ret = 1;
}
} else if (otyp ==DCP_EMS && drv_cnt != 1) {
ret = 1;
}
if (drv_cnt == 0) {
ret = 1;
}
if (f_cnt != 1) {
ret = 1;
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void err_msg(int msgno, int drv)
{
if (msgno == 1) {
if (ohlp == OFF) {
printf("fdu (Ver. %s) for FM TOWNS%37cBy T.O6809\n" , VER, ' ');
puts("Usage: fdu -? | -{f{1-4}|F|c|cc} [-B] [+{+|1-65535}] <Drive:>...");
} else {
printf("-- fdu (Ver. %s) -- for FM TOWNS -------"
"----------------------- By T.O6809 --\n" , VER);
puts("Usage: fdu -? | -{f{1-4}|F|c|cc} [-B] [+{+|1-65535}] <Drive:>...");
puts("----------------------------------------"
"---------------------------------------");
puts("-? Help");
puts("-f1 MS-DOS Format 640k[2DD] (80*2* 8* 512*2)");
puts("-f2 MS-DOS Format 720k[2DD] (80*2* 9* 512*2)");
puts("-f3 MS-DOS Format 1200k[2HC] (80*2*15* 512*1)");
puts("-f4 MS-DOS Format 1232k[2HD] (77*2* 8*1024*1)");
puts("-F MS-DOS Format FAT Only");
puts("-c MS-DOS Disk Copy");
puts("-cc MS-DOS Disk Copy (Write FD N times after reading source.)");
puts("-B BEEP ON");
puts("++ 65535 Repeat");
puts("+{1-65535} 1 - 65535 Repeat");
puts("<Drive:>... A: - P:");
puts("");
puts("Ex.)");
puts(" fdu -f4 +10 a: b: (format a: and format b:) * 10");
puts(" fdu -f3 a: (format /R a:)");
puts(" fdu -F +5 a: (format /C a:) * 5");
puts(" fdu -c +100 a: b: (diskcopy a: b:) * 100");
puts(" fdu -c a: a: (diskcopy a: a:)");
}
} else if (msgno == 2) {
if (drv_media == 2) {
puts("That is not FD. (Hard Disk)");
} else if (drv_media == 3) {
puts("That is not FD. (RAM Disk)");
} else if (drv_media == 5) {
puts("That is not FD. (ROM Dvice)");
} else {
puts("That is not FD. (Unknow Dvice)");
}
} else if (msgno == 3) {
CSL_TOP();
printf("%c: Can't format then change anther disk if ready, push any key.",
'A'+drv);
getch();
DEL_STR();
} else if (msgno == 4) {
CSL_TOP();
printf("%c: Unknow format.", 'A'+drv);
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void data_make(void)
{
int cnt, len, i, j, tmp;
for (i = 0; i < pr[odtp][9]; i++) { /* Gap0 */
buf1[i] = 0x4E;
}
cnt = pr[odtp][9]+pr[odtp][10];
for (i = pr[odtp][9]; i < cnt; i++) { /* Sync */
buf1[i] = 0;
}
if (pr[odtp][1] == MFM) {
buf1[cnt] = 0xF6; /* Index Mark */
buf1[cnt+1] = 0xF6;
buf1[cnt+2] = 0xF6;
buf1[cnt+3] = 0xFC; /* CRC */
} else {
buf1[cnt] = 0xFC; /* CRC */
}
cnt = pr[odtp][11]+pr[odtp][12];
for (i = pr[odtp][11]; i < cnt; i++) { /* Gap1 */
buf1[i] = 0x4E;
}
for (i = 0; i < pr[odtp][4]; i++) {
tmp = pr[odtp][14] * i;
for (j = 0; j < pr[odtp][10]; j++) { /* Sync */
buf1[tmp+cnt+j] = 0;
}
len = cnt + pr[odtp][10];
if (pr[odtp][1] == MFM) {
buf1[tmp+len++] = 0xF5; /* ID Address Mark*/
buf1[tmp+len++] = 0xF5;
buf1[tmp+len++] = 0xF5;
buf1[tmp+len++] = 0xFE;
} else {
buf1[tmp+len++] = 0xFE;
}
buf1[tmp+len++] = 0; /* Track Number */
buf1[tmp+len++] = 0; /* Cylnder Number */
buf1[tmp+len++] = (uchar)(i+1); /* Sector Number */
buf1[tmp+len++] = (uchar)pr[odtp][2]; /* Sec Len */
buf1[tmp+len++] = 0xF7;
for (j = 0; j < pr[odtp][13]; j++) { /* Gap2 */
buf1[tmp+len+j] = 0x4E;
}
len += pr[odtp][13];
for (j = 0; j < pr[odtp][10]; j++) { /* Sync */
buf1[tmp+len+j] = 0;
}
len += pr[odtp][10];
if (pr[odtp][1] == MFM) {
buf1[tmp+len++] = 0xF5; /* Data or */
buf1[tmp+len++] = 0xF5; /* Deleted DataMark*/
buf1[tmp+len++] = 0xF5;
buf1[tmp+len++] = 0xFB; /* CRC */
} else {
buf1[tmp+len++] = 0xFB; /* CRC */
}
for (j = 0; j < pr[odtp][3]; j++) { /* Data */
buf1[tmp+len+j] = 0xE5;
}
len += pr[odtp][3];
buf1[tmp+len++] = 0xF7; /* CRC */
for (j = 0; j < pr[odtp][7]; j++) { /* Gap3 */
buf1[tmp+len+j] = 0x4E;
}
}
tmp = pr[odtp][14]*(pr[odtp][4]-1)+len+j;
for (i = 0; i < pr[odtp][8]*5; i++) {
buf1[tmp + i] = 0x4E;
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_form(void)
{
int ret, i, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
static int f_old = 0xffff;
for (i = 0; i < drv_cnt; i++) {
if (odno[i] == f_old) {
CSL_TOP();
printf("%c: Change disk. [Push Any Key]", 'A'+odno[i]);
getch();
DEL_STR();
}
f_old = odno[i];
fd_ready1(odno[i]);
fd_mode_set(odno[i]);
CSL_TOP();
printf("%s Format %c: [%ld/%ld]\n",
type[odtp], odno[i]+'A', (long)rpt_cnt*drv_cnt+i+1, (long)orpt*drv_cnt);
while ((ret = fd_chk(odno[i])) != 0) {
err_msg(3, odno[i]);
}
time_get(&s_min, &s_sec, &s_hsec);
fd_form_sub(odno[i]);
init_ipl(odno[i]);
init_fat(odno[i]);
time_get(&e_min, &e_sec, &e_hsec);
if (s_min > e_min) e_min += 60;
if (s_hsec > e_hsec) {
e_hsec += 100;
e_sec--;
}
CSL_TOP();
printf("Finished (%3d.%02d sec)\n",
(e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
if (obep == ON) {
BEEP();
}
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_form_sub(int drv)
{
int i, j, ret, tmp;
ret = uDKB_restore(devno[drv]); /* シリンダ0へのシーク */
CSL_TOP();
printf("%02d/%02d Track Format", 0, pr[odtp][5]-1);
tmp = pr[odtp][11]+pr[odtp][12];
for (i = 0; i < pr[odtp][5]; i++) {
for (j = 0; j < pr[odtp][4]; j++) { /* Face 0 */
buf1[pr[odtp][14]*j+tmp+16] = (uchar)i;
buf1[pr[odtp][14]*j+tmp+17] = 0;
}
ret = uDKB_format(devno[drv], i, 0, buf1);
for (j = 0; j < pr[odtp][4]; j++) { /* Face 1 */
buf1[pr[odtp][14]*j+tmp+17] = 1;
}
ret = uDKB_format(devno[drv], i, 1, buf1);
CSL_TOP();
printf("%02d", i);
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void init_ipl(int drv)
{
int ret, secnum;
uchar *bf_p;
bf_p = malloc(pr[odtp][3]*pr[odtp][4]);
if (bf_p == NULL) {
puts("Malloc error\n");
exit(3);
}
memset(bf_p, 0, pr[odtp][3]*pr[odtp][4]);
*(bf_p+ 0) = 0xEB; /* IPL near jump */
*(bf_p+ 1) = 0x1C;
*(bf_p+ 2) = 0x90;
*(bf_p+ 3) = 0x46; /* F */
*(bf_p+ 4) = 0x44; /* D */
*(bf_p+ 5) = 0x55; /* U */
*(bf_p+ 6) = 0x20; /* */
*(bf_p+ 7) = 0x30; /* 0 */
*(bf_p+ 8) = 0x2E; /* . */
*(bf_p+ 9) = 0x39; /* 9 */
*(bf_p+10) = 0x31; /* 1 */
*(bf_p+11) = ipl[odtp][ 0]; /* Byte/Sector */
*(bf_p+12) = ipl[odtp][ 1];
*(bf_p+13) = ipl[odtp][ 2]; /* Sector/Cluster */
*(bf_p+14) = ipl[odtp][ 3]; /* Reserve Sector Number */
*(bf_p+15) = ipl[odtp][ 4];
*(bf_p+16) = ipl[odtp][ 5]; /* FAT Number */
*(bf_p+17) = ipl[odtp][ 6]; /* Root Directry Entry MAX */
*(bf_p+18) = ipl[odtp][ 7];
*(bf_p+19) = ipl[odtp][ 8]; /* Logical Sector Number */
*(bf_p+20) = ipl[odtp][ 9];
*(bf_p+21) = ipl[odtp][10]; /* Media ID Byte */
*(bf_p+22) = ipl[odtp][11]; /* Sector/FAT */
*(bf_p+23) = ipl[odtp][12];
*(bf_p+24) = ipl[odtp][13]; /* Sector/Track */
*(bf_p+25) = ipl[odtp][14];
*(bf_p+26) = ipl[odtp][15]; /* Head */
*(bf_p+27) = ipl[odtp][16];
*(bf_p+28) = ipl[odtp][17]; /* Hidden Sector */
*(bf_p+29) = ipl[odtp][18];
*(bf_p+30) = 0xEA; /* IPL Routine */
*(bf_p+31) = 0x00;
*(bf_p+32) = 0x00;
*(bf_p+33) = 0xFF;
*(bf_p+34) = 0xFF;
ret = uDKB_write(devno[drv], 0, 0, 1, pr[odtp][4], bf_p, &secnum);
free(bf_p);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_form_fat(void)
{
int i, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
static uint cnt;
for (i = 0; i < drv_cnt; i++) {
if (cnt++ != 0) {
CSL_TOP();
printf("%c: Change disk. [Push Any Key]", 'A'+odno[i]);
getch();
DEL_STR();
}
fd_ready1(odno[i]);
fd_ready2(odno[i]);
if (odtp == 0xffff) {
err_msg(4, odno[i]);
CSL_ON();
exit(4);
}
fd_mode_set(odno[i]);
CSL_TOP();
printf("%s Format (FAT) %c: [%ld/%ld]\n",
type[odtp], odno[i]+'A', (long)rpt_cnt*drv_cnt+i+1, (long)orpt*drv_cnt);
time_get(&s_min, &s_sec, &s_hsec);
init_fat(odno[i]);
time_get(&e_min, &e_sec, &e_hsec);
if (s_min > e_min) e_min += 60;
if (s_hsec > e_hsec) {
e_hsec += 100;
e_sec--;
}
CSL_TOP();
printf("Finished (%3d.%02d sec)\n",
(e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
if (obep == ON) {
BEEP();
}
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void init_fat(int drv)
{
int i, ret, secnum, size1, size2;
uchar *bf_p;
ret = uDKB_restore(devno[drv]); /* シリンダ0へのシーク */
bf_p = malloc(pr[odtp][3]*pr[odtp][4]*2);
if (bf_p == NULL) {
puts("Malloc error\n");
exit(3);
}
ret = uDKB_read(devno[drv], 0, 0, 1, pr[odtp][4], bf_p, &secnum);
ret = uDKB_read(devno[drv], 0, 1, 1, pr[odtp][4],
bf_p+pr[odtp][3]*pr[odtp][4], &secnum);
/* FAT Data and Root dir Size */
size1 = pr[odtp][3]*ipl[odtp][11]*ipl[odtp][5]; /* FAT Total Size */
size2 = ipl[odtp][6]*32; /* Root dir Size */
memset(bf_p+pr[odtp][3], 0, size1);
memset(bf_p+pr[odtp][3]+size1, 0xF6, size2);
*(bf_p+pr[odtp][3]+0) = ipl[odtp][10];
*(bf_p+pr[odtp][3]+1) = 0xFF;
*(bf_p+pr[odtp][3]+2) = 0xFF;
*(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+0) = ipl[odtp][10];
*(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+1) = 0xFF;
*(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+2) = 0xFF;
for (i = pr[odtp][3]+size1; i < pr[odtp][3]+size1+size2; i += 32) {
*(bf_p+i) = 0;
}
ret = uDKB_write(devno[drv], 0, 0, 1, pr[odtp][4], bf_p+0, &secnum);
ret = uDKB_write(devno[drv], 0, 1, 1, pr[odtp][4],
bf_p+pr[odtp][3]*pr[odtp][4], &secnum);
free(bf_p);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_copy()
{
int ret, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
if (otyp == DCP && cc_cnt++ != 0) {
CSL_TOP();
printf("%c:(src) Change disk. [Push Any Key]", 'A'+odno[0]);
getch();
DEL_STR();
}
if (otyp == DCP || (otyp ==DCP_EMS && cc_cnt == 0)) {
fd_ready2(odno[0]); /* Src Drive */
if (odtp == 0xffff) {
err_msg(4, odno[0]);
CSL_ON();
exit(4);
}
}
if (otyp == DCP && odno[0] != odno[1]) {
fd_ready1(odno[1]); /* Destination Drive */
}
if (otyp == DCP || (otyp ==DCP_EMS && cc_cnt == 0)) {
data_make();
}
fd_mode_set(odno[0]); /* Src Drive */
fd_mode_set(odno[1]); /* Destination Drive */
CSL_TOP();
printf("%s Disk Copy %c: -> %c: [%ld/%ld]\n",
type[odtp], odno[0]+'A', odno[1]+'A', (long)rpt_cnt+1, (long)orpt*drv_cnt);
if (otyp == DCP && odno[0] != odno[1]) {
while ((ret = fd_chk(odno[1])) != 0) {
err_msg(3, odno[1]);
}
}
time_get(&s_min, &s_sec, &s_hsec);
fd_copy_sub(odno[0], odno[1]);
time_get(&e_min, &e_sec, &e_hsec);
if (s_min > e_min) e_min += 60;
if (s_hsec > e_hsec) {
e_hsec += 100;
e_sec--;
}
CSL_TOP();
printf("Finished (%3d.%02d sec)\n",
(e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
if (obep == ON) {
BEEP();
}
cc_cnt++;
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_copy_sub(int drv1, int drv2)
{
ulong adr;
int i, ret, tmp;
static ulong bf_max, trk_siz, fd_siz;
static int bf_siz[80], loop;
static uchar huge *bf_p;
trk_siz = pr[odtp][3] * pr[odtp][4];
fd_siz = trk_siz * pr[odtp][5] * 2;
if ((otyp == DCP && drv1 == drv2) || (otyp == DCP_EMS && cc_cnt == 0)) {
if (ems_chk() == 0) {
if ((ems_alloc(&adr, &ems_handle)) == 0) {
ems_flg = 1;
bf_p = (uchar huge *)adr;
bf_max = 16L*1024*4;
}
}
}
if (otyp == DCP_EMS && ems_flg == 0) {
printf("No enough EMS, then option \"-cc\" can't use.");
end_fdu();
exit(3);
}
if (ems_flg == 0) {
for (bf_max = 0xA0000; bf_max > 0; bf_max -= trk_siz) {
bf_p = (uchar huge *)halloc(bf_max, sizeof(char));
if (bf_p != NULL) {
break;
}
}
}
if ((otyp == DCP_EMS && cc_cnt == 0)|| otyp == DCP) {
tmp = (uint)(bf_max / (trk_siz*2));
loop = pr[odtp][5] / tmp;
for (i = 0; i < loop; i++) {
bf_siz[i] = tmp;
}
if ((pr[odtp][5] % tmp) != 0) {
bf_siz[loop++] = (pr[odtp][5] % tmp);
}
}
ret = uDKB_restore(devno[drv1]); /* シリンダ0へのシーク */
ret = uDKB_restore(devno[drv2]); /* シリンダ0へのシーク */
if (ems_flg == 1) {
fd_copy_ems(drv1, drv2, loop, bf_siz, trk_siz, bf_p, ems_handle);
} else {
fd_copy_mem(drv1, drv2, loop, bf_siz, trk_siz, bf_p);
}
if (ems_flg == 1) {
if (otyp == DCP) {
ems_free(ems_handle);
ems_flg = 0;
}
} else {
hfree(bf_p);
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_copy_ems(int drv1, int drv2, int loop, int bf_siz[],
ulong trk_siz, uchar huge *bf_p, int handle)
{
int i, j, k, l;
int ret, secnum, tmp, track, page, rcnt = 0, ret1, ret2, dtp;
uint far *map_adr;
uint map_data[4*2];
if ((otyp == DCP && drv1 == drv2) || (otyp == DCP_EMS && cc_cnt == 0)) {
for (i = 0, page = 0, track = 0; i < loop; i++) {
for (j = 0; j < 4; j++) {
map_data[j*2] = page++;
map_data[j*2+1] = j;
}
map_adr = map_data;
ems_map(map_adr, handle);
for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
CSL_TOP();
printf("%02d/%02d Track Read ", j, pr[odtp][5]-1);
while (1) {
rcnt++;
ret = uDKB_read1(devno[drv1], j, 0, 1,pr[odtp][4],
bf_p+k*trk_siz*2, &secnum);
if (ret == 0) {
rcnt = 0;
break;
} else if (rcnt >= 2) {
printf("Read error [%x]", ret);
end_fdu();
exit(2);
}
}
while (1) {
rcnt++;
ret = uDKB_read1(devno[drv1], j, 1, 1,pr[odtp][4],
bf_p+k*trk_siz*2+trk_siz, &secnum);
if (ret == 0) {
rcnt = 0;
break;
} else if (rcnt >= 2) {
printf("Read error [%x]", ret);
end_fdu();
exit(2);
}
}
}
track += bf_siz[i];
}
}
if (drv1 == drv2 || (otyp == DCP_EMS && cc_cnt != 0)) {
CSL_TOP();
printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv2);
getch();
DEL_STR();
}
fd_ready1(drv2); /* Destination Drive */
while ((ret = fd_chk(drv2)) != 0) {
err_msg(3, drv2);
fd_ready1(drv2); /* Destination Drive */
}
tmp = pr[odtp][11]+pr[odtp][12];
for (i = 0, page = 0, track = 0; i < loop; i++) {
for (j = 0; j < 4; j++) {
map_data[j*2] = page++;
map_data[j*2+1] = j;
}
map_adr = map_data;
ems_map(map_adr, handle);
for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
dtp = dtp2;
rcnt = 0;
while (1) {
rcnt++;
if (odtp != dtp2) {
CSL_TOP();
printf("%02d/%02d Track Format", j, pr[odtp][5]-1);
for (l = 0; l < pr[odtp][4]; l++) { /* Face 0 */
buf1[pr[odtp][14]*l+tmp+16] = (uchar)j;
buf1[pr[odtp][14]*l+tmp+17] = 0;
}
ret = uDKB_format(devno[drv2], j, 0, buf1);
for (l = 0; l < pr[odtp][4]; l++) { /* Face 1 */
buf1[pr[odtp][14]*l+tmp+17] = 1;
}
ret = uDKB_format(devno[drv2], j, 1, buf1);
}
CSL_TOP();
printf("%02d/%02d Track Write ", j, pr[odtp][5]-1);
ret1 = uDKB_write1(devno[drv2], j, 0, 1,pr[odtp][4],
bf_p+k*trk_siz*2, &secnum);
ret2 = uDKB_write1(devno[drv2], j, 1, 1,pr[odtp][4],
bf_p+k*trk_siz*2+trk_siz, &secnum);
if (ret1 == 0 && ret2 == 0) {
dtp2 = dtp;
break;
} else if (rcnt >= 2) {
printf("Write error ");
end_fdu();
exit(2);
} else {
dtp2 = !odtp;
}
}
}
track += bf_siz[i];
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_copy_mem(int drv1, int drv2, int loop, int *bf_siz,
ulong trk_siz, uchar huge *bf_p)
{
int i, j, k, l;
int ret, secnum, tmp, track, rcnt = 0, ret1, ret2, dtp;
for (i = 0, track = 0; i < loop; i++) {
if (drv1 == drv2 && i != 0) {
CSL_TOP();
printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv1);
getch();
DEL_STR();
fd_ready3(drv1); /* Destination or Src Drive */
}
for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
CSL_TOP();
printf("%02d/%02d Track Read ", j, pr[odtp][5]-1);
while (1) {
rcnt++;
ret = uDKB_read1(devno[drv1], j, 0, 1,pr[odtp][4],
bf_p+k*trk_siz*2, &secnum);
if (ret == 0) {
rcnt = 0;
break;
} else if (rcnt >= 2) {
printf("Read error [%x]", ret);
end_fdu();
exit(2);
}
}
while (1) {
rcnt++;
ret = uDKB_read1(devno[drv1], j, 1, 1,pr[odtp][4],
bf_p+k*trk_siz*2+trk_siz, &secnum);
if (ret == 0) {
rcnt = 0;
break;
} else if (rcnt >= 2) {
printf("Read error [%x]", ret);
end_fdu();
exit(2);
}
}
}
if (drv1 == drv2) {
CSL_TOP();
printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv2);
getch();
DEL_STR();
fd_ready1(drv2); /* Destination Drive */
if (i == 0) {
printf("");
while ((ret = fd_chk(drv2)) != 0) {
err_msg(3, drv2);
fd_ready1(drv2); /* Destination Drive */
}
}
} else if (i == 0 && otyp == DCP_EMS) {
dtp2 = odtp;
}
tmp = pr[odtp][11]+pr[odtp][12];
for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
dtp = dtp2;
rcnt = 0;
while (1) {
rcnt++;
if (odtp != dtp2) {
CSL_TOP();
printf("%02d/%02d Track Format", j, pr[odtp][5]-1);
for (l = 0; l < pr[odtp][4]; l++) { /* Face 0 */
buf1[pr[odtp][14]*l+tmp+16] = (uchar)j;
buf1[pr[odtp][14]*l+tmp+17] = 0;
}
ret = uDKB_format(devno[drv2], j, 0, buf1);
for (l = 0; l < pr[odtp][4]; l++) { /* Face 1 */
buf1[pr[odtp][14]*l+tmp+17] = 1;
}
ret = uDKB_format(devno[drv2], j, 1, buf1);
}
CSL_TOP();
printf("%02d/%02d Track Write ", j, pr[odtp][5]-1);
ret1 = uDKB_write1(devno[drv2], j, 0, 1,pr[odtp][4],
bf_p+k*trk_siz*2, &secnum);
ret2 = uDKB_write1(devno[drv2], j, 1, 1,pr[odtp][4],
bf_p+k*trk_siz*2+trk_siz, &secnum);
if (ret1 == 0 && ret2 == 0) {
dtp2 = dtp;
break;
} else if (rcnt >= 2) {
printf("Write error ");
end_fdu();
exit(2);
} else {
dtp2 = !odtp;
}
}
}
track += bf_siz[i];
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int ems_chk(void)
{
union REGS inregs, outregs;
char ver[4];
int ret = 1, ret1, fhdl;
/* EMSの常駐の確認 */
if ((fhdl = open("EMMXXXX0", O_RDONLY)) != -1) {
inregs.x.ax = 0x4400;
inregs.x.bx = fhdl;
intdos(&inregs, &outregs);
if ((outregs.x.dx & 0x0080) != 0) { /* Device or File ? */
inregs.h.ah = 0x40;
int86(0x67, &inregs, &outregs);
if (outregs.h.ah == 0) { /* Get Status */
inregs.h.ah = 0x46;
int86(0x67, &inregs, &outregs);
if (outregs.h.ah == 0) { /* Get Version */
if (outregs.h.al >= 0x40) {
ret = 0;
}
}
}
}
}
return(ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int ems_alloc(ulong *adr, int *handle)
{
union REGS inregs, outregs;
struct SREGS segregs;
uint i;
int ret = 1, tmp;
int free_page, alloc_page;
static uint map[256];
static uint far *p;
while (1) {
inregs.h.ah = 0x42;
int86(0x67, &inregs, &outregs); /* Get Uballocated Page Count */
if (outregs.h.ah != 0) {
break;
}
free_page = outregs.x.bx;
tmp = (16*4)/((pr[odtp][3]*pr[odtp][4]*2)/1024);
alloc_page = pr[odtp][5] * 4 / tmp;
if ((tmp = alloc_page % 4) != 0) {
alloc_page+=(4-tmp);
}
if (free_page < alloc_page) {
break;
}
inregs.h.ah = 0x43;
inregs.x.bx = alloc_page;
int86(0x67, &inregs, &outregs); /* Allocated Pages */
if (outregs.h.ah != 0) {
break;
}
*handle = outregs.x.dx;
inregs.h.ah = 0x41;
int86(0x67, &inregs, &outregs); /* Get Page Frame Address */
if (outregs.h.ah != 0) {
break;
}
*adr = ((ulong)outregs.x.bx << 16);
p = map;
inregs.x.ax = 0x5800;
segregs.es = FP_SEG(p);
inregs.x.di = FP_OFF(p); /* Get Mappable Physical Address Array */
int86x(0x67, &inregs, &outregs, &segregs);
if (outregs.x.cx < 4 && outregs.h.ah != 0) {
break;
}
for (i = 0; i < outregs.x.cx; i++) {
if (map[i*2] == (uint)(*adr>>16)) {
if (map[i*2+1] == 0 && map[(i+1)*2+1] == 1 &&
map[(i+2)*2+1] == 2 && map[(i+3)*2+1] == 3 ) {
ret = 0;
break;
}
}
}
break;
}
return(ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int ems_map(int far *map, int handle)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret = 0;
inregs.x.ax = 0x5000; /* Map Multiple Pages */
inregs.x.dx = handle;
inregs.x.cx = 4;
segregs.ds = FP_SEG(map);
inregs.x.si = FP_OFF(map);
int86x(0x67, &inregs, &outregs, &segregs);
if (outregs.h.ah != 0) {
printf("ems_map err(%02x)\n", outregs.h.ah);
ret = 1;
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int ems_free(int handle)
{
union REGS inregs, outregs;
int ret = 0;
inregs.h.ah = 0x45; /* Deallocate Pages */
inregs.x.dx = handle;
int86(0x67, &inregs, &outregs);
if (outregs.h.ah != 0) {
ret = 1;
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_ready1(int drv)
{
uint status;
int ret;
while (1) {
ret = uDKB_rdstatus(devno[drv], &status);
if ((status & 0x01) != 0) {
CSL_TOP();
printf("%c: Disk device ready? [Push Any Key]", 'A'+drv);
getch();
DEL_STR();
} else if ((status & 0x02) != 0) {
CSL_TOP();
printf("%c: Can't write then push any key after release it's protect.",
'A'+drv);
getch();
DEL_STR();
} else {
break;
}
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_ready2(int drv)
{
uint status;
int i, ret, secnum;
DKB_SEC secid;
uchar bf[1024];
while (1) {
ret = uDKB_rdstatus(devno[drv], &status);
if ((status & 0x01) != 0) {
CSL_TOP();
printf("%c: Drive ready? [Push Any Key]", 'A'+drv);
getch();
DEL_STR();
} else {
break;
}
}
odtp = 0xffff;
/* odtp set */
if ((ret = uDKB_rdsecid(devno[drv], 0, 0, &secid)) == 0) {
for (i = 0; i < 7; i++) {
if ((uint)(pr[i][0] | pr[i][1]) == (status & 0x00F0)) {
if (secid.seclen == (uchar)pr[i][2]) {
odtp = i;
break;
}
}
}
if (odtp == 1) {
ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
if (bf[0x18] == 9) {
odtp = F720;
}
} else if (odtp == F1200) {
ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
if (bf[0x18] != 0x0f) {
odtp = 0xffff;
}
}
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_ready3(int drv)
{
uint status;
int ret;
while (1) {
ret = uDKB_rdstatus(devno[drv], &status);
if ((status & 0x01) != 0) {
CSL_TOP();
printf("%c: Drive ready? [Push Any Key]", 'A'+drv);
getch();
DEL_STR();
} else {
break;
}
}
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void fd_mode_set(int drv)
{
int ret;
uint mode1, mode2;
mode1 = pr[odtp][0] | pr[odtp][1] | pr[odtp][2];
mode2 = (pr[odtp][6] << 8) | pr[odtp][4];
ret = uDKB_setmode(devno[drv], mode1, mode2);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
int fd_chk(int drv)
{
int i, ret = 0, ret1 = 0, ret2 = 0, ret3 = 0;
int secnum, tmp;
uchar bf[1024];
uint status;
DKB_SEC secid;
dtp2 = 0xffff;
if (otyp != FRM) {
if ((ret = uDKB_rdstatus(devno[drv], &status)) == 0 &&
(ret = uDKB_rdsecid(devno[drv], 0, 0, &secid)) == 0 ) {
for (i = 0; i < 7; i++) {
if ((uint)(pr[i][0] | pr[i][1]) == (status & 0x00F0)) {
if (secid.seclen == (uchar)pr[i][2]) {
dtp2 = i;
break;
}
}
}
if (dtp2 == F640) {
ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
if (bf[0x18] == 9) {
dtp2 = F720;
}
} else if (dtp2 == F1200) {
ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
if (bf[0x18] != 0x0f) {
dtp2 = 0xffff;
}
}
}
}
if (dtp2 != odtp) {
fd_mode_set(drv);
ret = uDKB_restore(devno[drv]); /* シリンダ0へのシーク */
tmp = pr[odtp][11]+pr[odtp][12];
for (i = 0; i < pr[odtp][4]; i++) {
buf1[pr[odtp][14]*i+tmp+16] = 0;
buf1[pr[odtp][14]*i+tmp+17] = 0;
}
ret1 = uDKB_format(devno[drv], 0, 0, buf1);
ret2 = uDKB_chksec(devno[drv], 0, 0, 1, 1, &secnum);
ret3 = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
}
if (!(ret1 == 0 && ret2 == 0 && ret3 == 0)) {
ret = 1;
} else {
ret = 0;
}
return(ret);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void dump(uchar bf[], int size)
{
int cnt = 0, i, j;
do {
printf ("XXXX:%04X ", cnt*16);
for (i = 0; i < 16; i++) {
if (i == 8) {
printf("-");
printf("%02X", bf[(cnt*16)+i]);
} else {
printf(" %02X", bf[(cnt*16)+i]);
}
}
printf(" ");
for (j = 0; j < 16; j++) {
if (!(bf[(cnt*16)+j] >= 0x20 && bf[(cnt*16)+j] <= 0x7e)) {
printf(".");
} else {
printf ("%c", bf[(cnt*16)+j]);
}
}
printf("\n");
cnt++;
} while (cnt*16 < size);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void time_get(int *min, int *sec, int *hsec)
{
union REGS inregs, outregs;
inregs.h.ah = 0x2c;
intdos(&inregs, &outregs);
*min = outregs.h.cl;
*sec = outregs.h.dh;
*hsec = outregs.h.dl;
}
/*-------------------------------------------------------------------*/
/* CTRL+C Interrupt Routine */
/*-------------------------------------------------------------------*/
void interrupt far ctrl_c(void)
{
end_fdu();
exit(5);
}
/*-------------------------------------------------------------------*/
/* */
/*-------------------------------------------------------------------*/
void end_fdu(void)
{
static union REGS inregs, outregs;
if (ems_flg == 1) {
inregs.h.ah = 0x45; /* 使用領域の解放 */
inregs.x.dx = ems_handle;
int86(0x67, &inregs, &outregs);
}
COLOR_RED();
printf("Abnormal stop");
COLOR_WHITE();
CSL_ON();
}
/*-------------------------------------------------------------------*/
/* ドライブモードの設定 (FD) */
/*-------------------------------------------------------------------*/
int uDKB_setmode(int devno, uint mode1, uint mode2)
{
union REGS inregs, outregs;
int ret;
inregs.h.ah = 0x00; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.h.dl = (uchar)mode1; /* ドライブモード1 */
inregs.x.bx = mode2; /* ドライブモード2 */
int86(0x93, &inregs, &outregs);
ret = outregs.h.ah;
return (ret);
}
/*-------------------------------------------------------------------*/
/* ドライブモードの取り出し (FD) */
/*-------------------------------------------------------------------*/
int uDKB_rdmode(int devno, uint *mode1, uint *mode2)
{
union REGS inregs, outregs;
int ret;
inregs.h.ah = 0x01; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
int86(0x93, &inregs, &outregs);
*mode1 = outregs.h.dl; /* ドライブモード1 */
*mode2 = outregs.x.bx; /* ドライブモード2 */
ret = outregs.h.ah;
return (ret);
}
/*-------------------------------------------------------------------*/
/* ドライブステータ情報の取り出し (FD) */
/*-------------------------------------------------------------------*/
int uDKB_rdstatus(int devno, uint *status)
{
union REGS inregs, outregs;
int ret;
inregs.h.ah = 0x02; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.h.ch = 0x00; /* */
int86(0x93, &inregs, &outregs);
*status = outregs.h.dl;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* シリンダ0へのシーク (FD) */
/*-------------------------------------------------------------------*/
int uDKB_restore(int devno)
{
union REGS inregs, outregs;
int ret;
inregs.h.ah = 0x03; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = 0x00;
int86(0x93, &inregs, &outregs);
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* データの読み込み (FD) */
/*-------------------------------------------------------------------*/
int uDKB_read(int devno, int cylno, int headno, int secno, int seccnt,
char *buf1, int *secnum)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x05; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
inregs.h.dl = (uchar)secno; /* セクタ番号 */
inregs.x.bx = seccnt; /* セクタ数 */
segread(&segregs);
inregs.x.di = FP_OFF(buf1);
int86x(0x93, &inregs, &outregs, &segregs);
*secnum = outregs.x.bx;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* データの読み込み (FD) */
/*-------------------------------------------------------------------*/
int uDKB_read1(int devno, int cylno, int headno, int secno, int seccnt,
char huge *buf1, int *secnum)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x05; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
inregs.h.dl = (uchar)secno; /* セクタ番号 */
inregs.x.bx = seccnt; /* セクタ数 */
segregs.ds = FP_SEG(buf1);
inregs.x.di = FP_OFF(buf1);
int86x(0x93, &inregs, &outregs, &segregs);
*secnum = outregs.x.bx;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* データの書き込み (FD) */
/*-------------------------------------------------------------------*/
int uDKB_write(int devno, int cylno, int headno, int secno, int seccnt,
char *buf1, int *secnum)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x06; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
inregs.h.dl = (uchar)secno; /* セクタ番号 */
inregs.x.bx = seccnt; /* セクタ数 */
segread(&segregs);
inregs.x.di = FP_OFF(buf1);
int86x(0x93, &inregs, &outregs, &segregs);
*secnum = outregs.x.bx;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* データの書き込み (FD) */
/*-------------------------------------------------------------------*/
int uDKB_write1(int devno, int cylno, int headno, int secno, int seccnt,
char huge *buf1, int *secnum)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x06; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
inregs.h.dl = (uchar)secno; /* セクタ番号 */
inregs.x.bx = seccnt; /* セクタ数 */
segregs.ds = FP_SEG(buf1);
inregs.x.di = FP_OFF(buf1);
int86x(0x93, &inregs, &outregs, &segregs);
*secnum = outregs.x.bx;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* セクタの検査 (FD) */
/*-------------------------------------------------------------------*/
int uDKB_chksec(int devno, int cylno, int headno, int secno, int seccnt,
int *secnum)
{
union REGS inregs, outregs;
int ret;
inregs.h.ah = 0x07; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
inregs.h.dl = (uchar)secno; /* セクタ番号 */
inregs.x.bx = seccnt; /* セクタ数 */
int86(0x93, &inregs, &outregs);
*secnum = outregs.x.bx;
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* セクタIDの取り出し (FD) */
/*-------------------------------------------------------------------*/
int uDKB_rdsecid(int devno, int cylno, int headno, DKB_SEC *secid)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x09; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* */
inregs.h.dh = (uchar)headno; /* */
segread(&segregs);
inregs.x.di = FP_OFF(secid);
int86(0x93, &inregs, &outregs);
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* トラックのフォーマット (FD) */
/*-------------------------------------------------------------------*/
int uDKB_format(int devno, int cylno, int headno, uchar *buf1)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x0A; /* 機能コード */
inregs.h.al = (uchar)devno; /* デバイス番号 */
inregs.x.cx = cylno; /* シリンダ番号 */
inregs.h.dh = (uchar)headno; /* ベッド番号 */
segread(&segregs);
inregs.x.di = FP_OFF(buf1);
int86x(0x93, &inregs, &outregs, &segregs);
ret = outregs.h.ah;
if (ret == 0x80) {
ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
}
return (ret);
}
/*-------------------------------------------------------------------*/
/* システム情報の取得 */
/*-------------------------------------------------------------------*/
int system_get(uchar *p)
{
union REGS inregs, outregs;
struct SREGS segregs;
int ret;
inregs.h.ah = 0x00; /* 機能コード */
segread(&segregs);
inregs.x.di = FP_OFF(p);
int86x(0x8e, &inregs, &outregs, &segregs);
ret = outregs.h.ah;
return (ret);
}